package com.yhj.model;


import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author yaohj
 * @date 2024年12月11日 11:29
 */
@Component
public class JWTUtil {
    private static final String SECRET = "zhegelingpaiyoudianchang";
    public static final String USER = "ADMIN";
    public static final int EXPIRED = 24 * 60;

    @Autowired
    private RedisTemplate redisTemplate;

    // 生成Token
    public String createToken(User user)  {
        Date expiresAt = new Date(System.currentTimeMillis() +   60 * 1000); // 1分钟后过期
        String token = JWT.create()
                .withIssuer("auth0")
                .withClaim("user", user.getUsername())
                .withClaim("username", user.getUsername())
                .withSubject(JSONObject.toJSONString(user))
                .withExpiresAt(expiresAt)
                .sign(Algorithm.HMAC256(SECRET));
        return token;
    }

    // 验证Token并获取用户信息
    public User parseToken(String token) {
        JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt = verifier.verify(token);

        String userStr = jwt.getSubject();
        return JSONObject.parseObject(userStr, User.class);
    }

    // 验证Token并返回
    public boolean verifyToken(String token){
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    public String refreshToken(String token, User user) {
        String tokenKey = "sys:user:token" + token ;
        String cacheToken = String.valueOf(redisTemplate.opsForValue().get(tokenKey));
        if (!StringUtils.isEmpty(cacheToken)) {
            // 校验token有效性，注意需要校验的是缓存中的token
            if (!verifyToken(cacheToken)) {
                String newToken = createToken(user);
                // 设置超时时间
                redisTemplate.opsForValue().set(tokenKey, newToken, 2, TimeUnit.MINUTES);
                redisTemplate.opsForHash().delete("sys:user", token);
                redisTemplate.opsForHash().put("sys:user", newToken, user );
                return newToken;
            }
            return token;
        }
        return null;
    }
}
